﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.IO.Packaging;
using System.IO;
using ICSharpCode.SharpZipLib.Zip;
using ProjectStudy.App_Code;


namespace ProjectStudy
{
    public partial class zip解压文件 : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                
            }
        }

        //使用系统WindowsBase.dll文件（在C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.0/WindowsBase.dll）
        protected void Button1_Click(object sender, EventArgs e)
        {
            string FilePath = HttpContext.Current.Server.MapPath("UploadFiles/疑问.txt");
            string FilePath2 = HttpContext.Current.Server.MapPath("UploadFiles/22.zip");
            PackageFile(FilePath, FilePath2, true);
            Label1.Text = "压缩完成";
        }

        protected void Button4_Click(object sender, EventArgs e)
        {
            string Path1 = HttpContext.Current.Server.MapPath("UploadFiles");
            string Path2 = HttpContext.Current.Server.MapPath("UploadFiles/22.zip");
            UncompressFile(Path1, Path2, true);
            Label1.Text = "解压完成";

        }

        protected void Button2_Click(object sender, EventArgs e)
        {
            List<string> FilePath1 = new List<string>();
            FilePath1.Add(HttpContext.Current.Server.MapPath("UploadFiles/1.txt"));
            FilePath1.Add(HttpContext.Current.Server.MapPath("UploadFiles/2.txt"));
            string FilePath2 = HttpContext.Current.Server.MapPath("UploadFiles/1.zip");
             Zip(FilePath1, FilePath2, 1);
            Label2.Text = "压缩完成";
        }

        protected void Button3_Click(object sender, EventArgs e)
        {
            string FilePath1 = HttpContext.Current.Server.MapPath("UploadFiles");
            string FilePath2 = HttpContext.Current.Server.MapPath("UploadFiles/1.zip");
            UnZip(FilePath2, FilePath1, 10);
            Label2.Text = "解压完成";
        }

//--------------------------------使用系统Windows.Base.dll程序集压缩/解压文件----------------------------------------------------
        /// <summary>
        /// 
        /// </summary>
        /// <param name="fileName">要压缩的文件绝对路径</param>
        /// <param name="compressedFileName">要解压的文件绝对路径</param>
        /// <param name="overrideExisting">如果存在是否覆盖</param>
        /// <returns></returns>
        static bool PackageFile(string fileName, string compressedFileName, bool overrideExisting)
        {
            bool result = false;

            if (!File.Exists(fileName))
            {
                return result;
            }

            if (!overrideExisting && File.Exists(compressedFileName))
            {
                return result;
            }

            try
            {
                Uri partUriDocument = PackUriHelper.CreatePartUri(new Uri(Path.GetFileName(fileName), UriKind.Relative));

                using (Package package = Package.Open(compressedFileName, FileMode.OpenOrCreate))
                {
                    if (package.PartExists(partUriDocument))
                    {
                        package.DeletePart(partUriDocument);
                    }

                    PackagePart packagePartDocument = package.CreatePart(partUriDocument, "", CompressionOption.Maximum);
                    using (FileStream fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read))
                    {
                        fileStream.CopyTo(packagePartDocument.GetStream());
                    }
                }
                result = true;
            }
            catch (Exception e)
            {
                throw new Exception("Error zipping file " + fileName, e);
            }

            return result;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="folderName">解压后绝对路径</param>
        /// <param name="compressedFileName">要解压的文件绝对路径</param>
        /// <param name="overrideExisting">如果存在是否覆盖</param>
        /// <returns></returns>
        static bool UncompressFile(string folderName, string compressedFileName, bool overrideExisting)
        {
            bool result = false;
            try
            {
                if (!File.Exists(compressedFileName))
                {
                    return result;
                }

                DirectoryInfo directoryInfo = new DirectoryInfo(folderName);
                if (!directoryInfo.Exists)
                    directoryInfo.Create();

                using (Package package = Package.Open(compressedFileName, FileMode.Open, FileAccess.Read))
                {
                    foreach (PackagePart packagePart in package.GetParts())
                    {
                        ExtractPart(packagePart, folderName, overrideExisting);
                    }
                }

                result = true;
            }
            catch (Exception e)
            {
                throw new Exception("Error unzipping file " + compressedFileName, e);
            }

            return result;
        }

        static void ExtractPart(PackagePart packagePart, string targetDirectory, bool overrideExisting)
        {
            string stringPart = targetDirectory + HttpUtility.UrlDecode(packagePart.Uri.ToString()).Replace('\\', '/');

            if (!Directory.Exists(Path.GetDirectoryName(stringPart)))
                Directory.CreateDirectory(Path.GetDirectoryName(stringPart));

            if (!overrideExisting && File.Exists(stringPart))
                return;
            using (FileStream fileStream = new FileStream(stringPart, FileMode.Create))
            {
                packagePart.GetStream().CopyTo(fileStream);
            }
        }            
//--------------------------------使用系统Windows.Base.dll程序集压缩/解压文件----------------------------------------------------

        /// <summary>
        /// 文件压缩
        /// </summary>
        /// <param name="SrcFile">要压缩的文件路径列表</param>
        /// <param name="DstFile">生成的压缩文件存放路径</param>
        /// <param name="BufferSize">缓冲区大小</param>
        public static void Zip(List<string> SrcFile, string DstFile, int BufferSize)
        {            
            FileStream fileStreamOut = new FileStream(DstFile, FileMode.Create, FileAccess.Write);
            ZipOutputStream zipOutStream = new ZipOutputStream(fileStreamOut);
            byte[] buffer = new byte[BufferSize];
            
            for (int i = 0; i < SrcFile.Count; i++)
            {
                FileStream fileStreamIn = new FileStream(SrcFile[i], FileMode.Open, FileAccess.Read);
                ZipEntry entry = new ZipEntry(Path.GetFileName(SrcFile[i]));
                zipOutStream.PutNextEntry(entry);
                int size;
                do
                {
                    size = fileStreamIn.Read(buffer, 0, buffer.Length);
                    zipOutStream.Write(buffer, 0, size);
                }
                while (size > 0);
                fileStreamIn.Close();
            }
            zipOutStream.Close();
            fileStreamOut.Close();            
        }

        /// <summary>
        /// 解压文件
        /// </summary>
        /// <param name="SrcFile">要解压的压缩文件路径</param>
        /// <param name="DstFile">解压文件存放路径</param>
        /// <param name="BufferSize">缓冲区大小</param>
        public static void UnZip(string SrcFile, string DstFile, int BufferSize)
        {
            FileStream fileStreamIn = new FileStream(SrcFile, FileMode.Open, FileAccess.Read);
            ZipInputStream zipInStream = new ZipInputStream(fileStreamIn);
            ZipEntry entry = zipInStream.GetNextEntry();
            while(entry!=null)
            {
                FileStream fileStreamOut = new FileStream(DstFile + @"\" + entry.Name, FileMode.Create, FileAccess.Write);
                int size;
                byte[] buffer = new byte[BufferSize];
                do
                {
                    size = zipInStream.Read(buffer, 0, buffer.Length);
                    fileStreamOut.Write(buffer, 0, size);
                }
                while (size > 0);
                fileStreamOut.Close();
                entry = zipInStream.GetNextEntry();
            }            
            zipInStream.Close();            
            fileStreamIn.Close();
        }
    }
}